package com.hsnn.medstgmini.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;

import com.hsnn.medstgmini.base.dict.model.DicExperttype;
import com.hsnn.medstgmini.base.std.model.StdExpert;
import com.hsnn.medstgmini.pro.project.model.BidExpertExtractListRuleList;
import com.hsnn.medstgmini.pro.project.model.BidExpertExtractRule;
import com.hsnn.medstgmini.pro.project.model.BidExpertType;
import com.hsnn.medstgmini.pro.project.model.BidProjExpert;
import com.hsnn.medstgmini.pro.project.model.RuleHospType;
import com.hsnn.medstgmini.pro.project.model.form.BidExpertExtractRuleListForm;
import com.hsnn.medstgmini.pro.project.service.BidExpertExtractRuleManager;

@Component
public class ExpertExtractImpl implements ExpertExtract{
	@Autowired
	private static final String String = null;
	@Autowired
	private HttpServletRequest request;
	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;
	@Autowired
	private BidExpertExtractRuleManager bidExpertExtractManager;
	
	///////////////////////////////////////////////////////////////////////////////////////////
	
	/**
	 * @category 抽取专家
	 * @Auther 徐国鹏
	 * @date 2015年10月12日 下午4:05:01
	 * @param list
	 * @return List<BidExpertExtractListRuleList>
	 */
	public List<BidProjExpert> expertss(List<BidExpertExtractListRuleList> list, String id,Model model){
		String[] extractNum = id.split(",");
		//BidExpertExtractListRuleList extractNum = new  BidExpertExtractListRuleList();
		List<BidProjExpert> bidProjExpertList = new ArrayList<BidProjExpert>();
		List<BidExpertExtractListRuleList> expert = extractExpertss(list);
		List<BidExpertExtractListRuleList> expertExperact = new ArrayList<BidExpertExtractListRuleList>();
		for(int i = 0; i < expert.size(); i++){
			expert.addAll(extractExperts(expert.get(i),expertExperact));//根据一条规则抽取专家 
		}
		List<BidExpertExtractListRuleList> list1 = new ArrayList<BidExpertExtractListRuleList>();//最多人数
		List<BidExpertType> list2 = new ArrayList<BidExpertType>();//专家分类
		List<RuleHospType> list3 = new ArrayList<RuleHospType>();//医疗机构类型
		String extractNum1 = request.getParameter("cityExtractNum");
		String extractNum2 = request.getParameter("countyExtractNum");
		String extractNum3 = request.getParameter("rootExtractNum");
		for(int i = 0; i< extractNum.length; i++){
			String ruleId = request.getParameter("ruleId");
//			String expertTypeId = request.getParameter("expertTypeId");
			BidExpertExtractListRuleList expertRule1 = (BidExpertExtractListRuleList) bidExpertExtractManager.getRuleByIdList(ruleId);
			model.addAttribute("list", list);
			BidExpertType expertRule2 = bidExpertExtractManager.getBidExpertType(ruleId);//专家分类
			model.addAttribute("list", list);
			RuleHospType expertRule3 = (RuleHospType) bidExpertExtractManager.getHospRuleByIdList(ruleId);//医疗机构类型
			model.addAttribute("list", list);
			if(extractNum1.length() < list1.size()){
				int sum = (int) i;
				Collections.shuffle(list); // 混乱的意思 
			    System.out.println(list);
				Math.floor(sum);
				list1.add(expertRule1);
			}
			if(extractNum2.length() < list2.size()){
				int a = (int) i;
				Collections.shuffle(list); // 混乱的意思 
			    System.out.println(list);
				Math.floor(a);
				list2.add(expertRule2);
			}
			if(extractNum3.length() < list3.size()){
				int a = (int) i;
				Collections.shuffle(list); // 混乱的意思 
			    System.out.println(list);
				Math.floor(a);
				list3.add(expertRule3);
			}
			expert.addAll(expert );
		}
		return bidProjExpertList;
	}
	
	/**
	 * @category 根据医疗类型+专家类型查询所有
	 * @Auther 徐国鹏
	 * @date 2015年10月12日 下午14:20:04
	 * @param list
	 * @return List<BidExpertExtractListRuleList>
	 */
	@SuppressWarnings("unchecked")
	private List<BidExpertExtractListRuleList> extractExpertss(List<BidExpertExtractListRuleList> list) {
		Session session = sessionFactory.getCurrentSession();
		StringBuffer sql = new StringBuffer();
		sql.append(" select a.expert_id,a.name from std_expert a "); 
		sql.append(" left join std_hospinfo b on a.company_id=b.hosp_id ");
		sql.append(" left join dic_exper_ettype c on c.expert_id=a.expert_id ");
		sql.append(" where b.hosp_classify in (:hospClassify) and c.expert_type_id= :expertEtypeId  ");
		sql.append(" and not exists  ");
		sql.append(" (select * from bid_projexpert d where d.rule_id=:ruleId and d.expert_id=a.expert_id) ");
		Query query = session.createSQLQuery(sql.toString()).addEntity(BidExpertExtractListRuleList.class);
		query.setParameter("expertId",  list);
		query.setParameter("updDatetimes", list);
		List<BidExpertExtractListRuleList> list1 = query.list();
		return list1;
	}

	/**	
	 * @category 排除所选的，在随机选择一个
	 * @Auther 徐国鹏
	 * @date 2015年10月12日 下午3:47:29
	 * @param list
	 * @return int
	 */
	@SuppressWarnings("unchecked")
	public List<BidExpertExtractListRuleList> extractExperts(BidExpertExtractListRuleList expertId , List<BidExpertExtractListRuleList> expertExperact) {
			Session session = sessionFactory.getCurrentSession();
			StringBuffer sql = new StringBuffer();
			sql.append(" select a.expert_id,a.name from std_expert a  "); 
			sql.append(" left join std_hospinfo b on a.company_id=b.hosp_id ");
			sql.append(" left join dic_exper_ettype c on c.expert_id=a.expert_id ");
			sql.append(" where b.hosp_classify in (:hospClassify) and c.expert_type_id= :expertEtypeId ");
			sql.append(" and not exists   ");
			sql.append(" (select * from bid_projexpert d where d.rule_id=:ruleId and d.expert_id=a.expert_id) ");
			sql.append(" order by RAND() ");
			Query query = session.createSQLQuery(sql.toString()).addEntity(BidExpertExtractListRuleList.class);
			query.setParameter("expertId", expertId);
			query.setParameter("updDatetimes", expertExperact);
			List<BidExpertExtractListRuleList> list = query.list();
			return list;
		}

	
	
	/////////////////////////////////////////////////////////////////////////////////////////////
   /**
    * @category 抽取专家
    * @author zhuqi
    * @date 2015年9月4日20:56:03
    * @param List<BidExpertExtractRule> list：待抽取的规则集合 
    * @return List<BiProjExpert> ：返回项目专家关系列表
    */
	@Override
	public List<BidProjExpert> extractExpert(List<BidExpertExtractRuleListForm> list) {
		List<BidProjExpert> bidProjExpertList = new ArrayList<BidProjExpert>();
		List<BidExpertExtractRuleListForm> ruleToBeExecuteList = ruleListToBeExecute(list);//不抽取类别
		List<String> expertIdAreadyExptract = new ArrayList<String> ();
		for(int i = 0; i < ruleToBeExecuteList.size(); i++){
			bidProjExpertList.addAll(ExtractExpertThroughOneRule(ruleToBeExecuteList.get(i),expertIdAreadyExptract));//根据一条规则抽取专家
		}
		return bidProjExpertList;
	}
	
	 /**
	    * @category 设置不抽取类别
	    * @author zhuqi
	    * @param 
	    * @return List<BiProjExpert> 
	    */
	public List<BidExpertExtractRuleListForm> ruleListToBeExecute(List<BidExpertExtractRuleListForm> list){
		for(int i = 0; i < list.size();i++){
			BidExpertExtractRuleListForm rule = list.get(i);
		     rule.setExpertTypeIdNotToExtract(getALLRuleIdOfList(rule,list));//设置不抽取专家类别
		}
		return list;
	}
	/**
	 * @category 获取不抽取的专家类别
	 * @author 周奇
	 * @date 2015年9月4日20:52:10
	 * @param BidExpertExtractRule extractRule：待抽取专家类别
	 * @param List<BidExpertExtractRule> list:共同执行的其他专家类别
	 * @return List<String>
	 */
	public List<String> getALLRuleIdOfList(BidExpertExtractRuleListForm extractRule, List<BidExpertExtractRuleListForm> list){
		List<String> ruleIdlist = new ArrayList<String>();
		for(int i = 0; i< list.size(); i++){
			BidExpertExtractRuleListForm rule = list.get(i);
			ruleIdlist.add(rule.getExpertTypeId());
		}
		ruleIdlist.remove(extractRule.getExpertTypeId());
		return ruleIdlist;
	}
	
	/**
	 * @category 获取子类规则
	 * @param bidExpertExtractRule 待判断规则
	 * @param list 所有规则列表
	 * @return
	 */
	public List<BidExpertExtractRule> getSubRule(BidExpertExtractRule extractRule,
			          List<BidExpertExtractRule> list){
		List<BidExpertExtractRule> subRuleList = new ArrayList<BidExpertExtractRule>();
		for(int i = 0; i < list.size(); i++){
			if(extractRule.getRuleId().equals(list.get(i).getFatherRuleId())){
				subRuleList.add(list.get(i));
			}
		}
		return subRuleList;
	}
	
	/**
	 * @category 根据一条规则抽取专家
	 * @author 周奇
	 * @date 2015年9月4日20:53:32
	 * @param BidExpertExtractRule bidExpertExtractRule：一条规则
	 * @param List<String> expertIdAreadyExtract:已经抽取过的专家id列表表示不再抽取
	 * @param List<BidProjExpert> projExpertList：共同执行的其他规则
	 */
	public List<BidProjExpert> ExtractExpertThroughOneRule(BidExpertExtractRuleListForm bidExpertExtractRule, List<String> expertIdAreadyExtract){
		String expertTypeId = bidExpertExtractRule.getExpertTypeId();
		List<DicExperttype> typeList = getAllSubExpertType(expertTypeId);//根据id获取所有的子类专家类别
		List<String> typeIdList = new ArrayList<String>();
		for(int i= 0; i < typeList.size(); i++){
			typeIdList.add(typeList.get(i).getDicExperttypeId());
		}
		List<String> notExtractTypeId = bidExpertExtractRule.getExpertTypeIdNotToExtract();//获取不抽取的专家类别
		typeIdList.removeAll(notExtractTypeId);//删除不抽取的专家类别
		Session session = sessionFactory.getCurrentSession();
		StringBuffer sql = new StringBuffer();
		sql.append(" select a.expert_id,a.name from std_expert a "); 
		sql.append(" left join std_hospinfo b on a.company_id=b.hosp_id ");
		sql.append(" left join dic_exper_ettype c on c.expert_id=a.expert_id ");
		sql.append(" where b.hosp_classify in (:hospClassify) and c.expert_type_id= :expertEtypeId  ");
		sql.append(" and not exists  ");
		sql.append(" (select * from bid_projexpert d where d.rule_id=:ruleId and d.expert_id=a.expert_id) ");
		Query query = session.createSQLQuery(sql.toString()).addEntity(StdExpert.class);
		query.setParameter("count", bidExpertExtractRule.getCount());
		@SuppressWarnings("unchecked")
		List<StdExpert> expertList = query.list();
		List<BidProjExpert> bidProjExpertList = new ArrayList<BidProjExpert>();
		for(int i = 0; i < expertList.size();i++){
			StdExpert stdExpert = expertList.get(i);
			BidProjExpert bidProjExpert = new BidProjExpert();
			bidProjExpert.setProjExpertId(UUID.randomUUID().toString());
			bidProjExpert.setProjId(bidExpertExtractRule.getProjId());
			bidProjExpert.setExpertId(stdExpert.getExpertId());
			bidProjExpert.setRuleId(bidExpertExtractRule.getRuleId());
			bidProjExpertList.add(bidProjExpert);
			expertIdAreadyExtract.add(stdExpert.getExpertId());
		}
		return bidProjExpertList;
	}
	
	/**
	 * @category 根据专家类别Id获取专家类型
	 * @param list
	 * @return List<BidExpertExtractRule>
	 */
	public DicExperttype getExpertTypeById(String id){
		Session session = sessionFactory.getCurrentSession();
		return (DicExperttype)session.get(DicExperttype.class, id);
	}
	/**
	 * @category 根据类别id获取专家类别下级类别
	 * @param list
	 * @return List<BidExpertExtractRule>
	 */
	@SuppressWarnings("unchecked")
	public List<DicExperttype> getSubTypeByid(String id){
		Session session = sessionFactory.getCurrentSession();
	    StringBuffer sql = new StringBuffer();
	    sql.append("select * from dic_experttype A where A.father_experttype_id = :id");
	    Query query = session.createSQLQuery(sql.toString()).addEntity(DicExperttype.class);
	    query.setParameter("id", id);
	    return query.list();
	}
	/**
	 * @category 根据类型id获取类型所处的级别
	 * @param experttypId
	 * @return
	 */
	public int getLevelOfExperttype(String experttypId){
		int i=1;
		String fatherExpertId = experttypId;
		while(true){
			fatherExpertId = getExpertTypeById(fatherExpertId).getFatherExperttypeId();//根据专家类别Id获取专家类型
			if(!fatherExpertId.equals("0")){
				i++;
			}else{
				break;
			}
		}
		return i;
	}
	/**
	 * @category 根据id获取一个专家类别的所有子类
	 * @author 周奇
	 * @date 2015年9月4日20:58:19
	 * @param id
	 * @return List<DicExperttype> ：返回所有子类列表
	 */
	public List<DicExperttype> getAllSubExpertType(String id){
		List<DicExperttype> list = new ArrayList<DicExperttype>();
		list.add(getExpertTypeById(id));//根据专家类别Id获取专家类型
		for(int i = 0; i< list.size();i++){
			List<DicExperttype> tempList = this.getSubTypeByid(list.get(i).getDicExperttypeId());
			if(tempList.size() < 0){
				break;
			}
			list.addAll(tempList);
		}
		return list;
	}

	
	
	
}
